package ru.myrtle.umf.tools.ugen;

import ru.myrtle.umf.UClass;
import ru.myrtle.umf.UDataType;
import ru.myrtle.umf.UEnumeration;
import ru.myrtle.umf.UEnumerationLiteral;
import ru.myrtle.umf.UPackage;
import ru.myrtle.umf.codegen.GenArtifact;
import ru.myrtle.umf.codegen.GenDomain;
import ru.myrtle.umf.codegen.GenModel;
import ru.myrtle.umf.codegen.GenRule;
import ru.myrtle.umf.tools.ugen.templates.UConverterStubTemplate;
import ru.myrtle.umf.tools.ugen.templates.UConverterTemplate;
import ru.myrtle.umf.tools.ugen.templates.UEnumerationDelegateImplTemplate;
import ru.myrtle.umf.tools.ugen.templates.UEnumerationDelegateTemplate;
import ru.myrtle.umf.tools.ugen.templates.UEnumerationTemplate;
import ru.myrtle.umf.tools.ugen.templates.UFactoryTemplate;
import ru.myrtle.umf.tools.ugen.templates.UModelTemplate;
import ru.myrtle.umf.tools.ugen.templates.UObjectImplTemplate;
import ru.myrtle.umf.tools.ugen.templates.UObjectOpStubTemplate;
import ru.myrtle.umf.tools.ugen.templates.UObjectOpTemplate;
import ru.myrtle.umf.tools.ugen.templates.UObjectTemplate;

import java.util.ArrayList;
import java.util.Collection;

public final class UGen {

    private static final String CHARSET_CP1251 = "CP1251";
    private static final String CHARSET_UTF8 = "UTF8";

    private static final String DOMAIN_SRC = "src";

    /*
     *
     */

    private static class Packages implements GenRule.Selector<UGenConfig> {

        @Override
        public Collection<?> getContent(UGenConfig context) {
            return context.getPackages();
        }
    }

    /*
     *
     */

    private static class Classes implements GenRule.Selector<UGenConfig> {

        @Override
        public Collection<?> getContent(UGenConfig context) {
            Collection<UClass> objects = new ArrayList<UClass>();

            for (UPackage uPackage : context.getPackages()) {
                objects.addAll(
                        uPackage.getClasses()
                );
            }

            return objects;
        }
    }

    /*
     *
     */

    private static class Enumerations implements GenRule.Selector<UGenConfig> {

        @Override
        public Collection<?> getContent(UGenConfig context) {
            Collection<UEnumeration> objects = new ArrayList<UEnumeration>();

            for (UPackage uPackage : context.getPackages()) {
                objects.addAll(
                        uPackage.getEnumerations()
                );
            }

            return objects;
        }
    }

    /*
     *
     */

    private static class EnumerationLiterals implements GenRule.Selector<UGenConfig> {

        @Override
        public Collection<?> getContent(UGenConfig context) {
            Collection<UEnumeration> enumerations = new ArrayList<UEnumeration>();

            for (UPackage uPackage : context.getPackages()) {
                enumerations.addAll(
                        uPackage.getEnumerations()
                );
            }

            Collection<UEnumerationLiteral> literals = new ArrayList<UEnumerationLiteral>();

            for (UEnumeration enumeration : enumerations) {
                literals.addAll(
                        enumeration.getLiterals()
                );
            }

            return literals;
        }
    }

    /*
     *
     */

    private static class DataTypes implements GenRule.Selector<UGenConfig> {

        @Override
        public Collection<?> getContent(UGenConfig context) {
            Collection<UDataType> objects = new ArrayList<UDataType>();

            for (UPackage uPackage : context.getPackages()) {
                objects.addAll(
                        uPackage.getDataTypes()
                );
            }

            return objects;
        }
    }

    /*
     *
     */

    public static final GenModel<UGenConfig, UGenConfig> GENERATOR = new GenModel<UGenConfig, UGenConfig>(
            "UGen",
            new GenRule<UGenConfig, UGenConfig>(
                    "Packages",
                    new Packages(),
                    new GenDomain<UGenConfig>(
                            DOMAIN_SRC,
                            new GenArtifact<UGenConfig>(new UFactoryTemplate(), CHARSET_CP1251),
                            new GenArtifact<UGenConfig>(new UModelTemplate(), CHARSET_CP1251)
                    )
            ),
            new GenRule<UGenConfig, UGenConfig>(
                    "Enumerations",
                    new Enumerations(),
                    new GenDomain<UGenConfig>(
                            DOMAIN_SRC,
                            new GenArtifact<UGenConfig>(new UEnumerationTemplate(), CHARSET_CP1251),
                            new GenArtifact<UGenConfig>(new UEnumerationDelegateTemplate(), CHARSET_CP1251)
                    )
            ),
            new GenRule<UGenConfig, UGenConfig>(
                    "EnumerationLiterals",
                    new EnumerationLiterals(),
                    new GenDomain<UGenConfig>(
                            DOMAIN_SRC,
                            new GenArtifact<UGenConfig>(new UEnumerationDelegateImplTemplate(), CHARSET_CP1251)
                    )
            ),
            new GenRule<UGenConfig, UGenConfig>(
                    "Classes",
                    new Classes(),
                    new GenDomain<UGenConfig>(
                            DOMAIN_SRC,
                            new GenArtifact<UGenConfig>(new UObjectTemplate(), CHARSET_CP1251),
                            new GenArtifact<UGenConfig>(new UObjectImplTemplate(), CHARSET_CP1251),
                            new GenArtifact<UGenConfig>(new UObjectOpTemplate(), CHARSET_CP1251),
                            new GenArtifact<UGenConfig>(new UObjectOpStubTemplate(), CHARSET_CP1251)
                    )
            ),
            new GenRule<UGenConfig, UGenConfig>(
                    "DataTypes",
                    new DataTypes(),
                    new GenDomain<UGenConfig>(
                            DOMAIN_SRC,
                            new GenArtifact<UGenConfig>(new UConverterTemplate(), CHARSET_CP1251),
                            new GenArtifact<UGenConfig>(new UConverterStubTemplate(), CHARSET_CP1251)
                    )
            )
    );
}
